<template>
  <div class="w-100">
    <el-select filterable multiple v-model="tagSelectedList" placeholder="请选择几个标签" :loading="openTagSearchLoading" :filter-method="filterTag">
      <template #header>
        <div class="flex-container flex-row-left txt-gray-90 txt-0_9em mouse-default">
          <el-icon><QuestionFilled /></el-icon>
          <div class="ml-0_5em">仅展示使用最频繁的标签，可输入名称在标签库搜索</div>
        </div>
      </template>
      <el-option v-for="tag in tagList" :label="tag" :value="tag" :key="tag" />
      <template #footer>
        <el-button v-if="!addTagInputShow" text bg size="small" @click="openAddTagInput"> 添加一个标签 </el-button>
        <div v-else>
          <el-input v-model="tagName" class="option-input" placeholder="输入标签名称" size="small" @keydown.enter="addTag" />
          <div class="mt-0_5em">
            <el-button type="primary" size="small" @click="addTag"> 添加 </el-button>
            <el-button size="small" @click="cancelAddTag">取消</el-button>
          </div>
        </div>
      </template>
    </el-select>
  </div>
</template>

<script setup>
import { ref, onMounted, defineEmits, watch } from 'vue'
import { QuestionFilled } from '@element-plus/icons-vue'
import { isEmpty, isNotEmpty } from '@/utils/validate'
import Tag from '@/api/blog/tag'
import { ElMessage } from 'element-plus'

// 生命周期, 初始化数据
onMounted(() => {
  searchTag()
})

const props = defineProps({
  modelValue: {
    type: Array,
    default: [],
  },
})

// 选中的标签列表
const tagSelectedList = ref(props.modelValue)

const emits = defineEmits(['update:modelValue'])
// 监听选中的标签列表的变化
watch(
  () => props.modelValue,
  (modelValue) => {
    tagSelectedList.value = modelValue
  }
)
// 监听选中的标签列表的变化
watch(
  () => tagSelectedList.value,
  (value) => {
    emits('update:modelValue', value)
  }
)

// 标签列表
const tagList = ref([])

// 远程搜索标签时候，开启 loading 动画的开关
const openTagSearchLoading = ref(false)

// 搜索标签函数的最后一次执行时间，利用该时间进行防抖操作
let filterTagLastTime = +new Date()
// 执行搜索标签函数的延时任务ID
let filterTagTimeoutId = null
// 搜索标签函数的最后一次搜索内容
let filterTagLastQueryName = ''

// 过滤标签, 将 searchTag 方法加上防抖
function filterTag(tagName) {
  console.log(tagName, Object.prototype.toString.call(tagName).toLowerCase())
  // 计算上一次调用的时间间隔
  let time = +new Date() - filterTagLastTime
  // 记录本次触发时间
  filterTagLastTime = +new Date()
  // 如果两次输入结果一致，就不触发搜索。避免下拉框出现抖动
  if (filterTagLastQueryName === tagName) {
    return
  }
  filterTagLastQueryName = tagName
  // 如果时间大于 400， 就创建延时函数, 延迟执行
  if (time > 400) {
    filterTagTimeoutId = setTimeout(() => {
      searchTag(tagName)
    }, 400)
  } else {
    // 如果两次调用时间小于 400， 就将上一个延时函数取消，创建新的延时函数
    if (filterTagTimeoutId) {
      clearTimeout(filterTagTimeoutId)
    }
    filterTagTimeoutId = setTimeout(() => {
      searchTag(tagName)
    }, 400)
  }
}
// 远程搜索标签
function searchTag(tagName) {
  openTagSearchLoading.value = true
  if (isNotEmpty(tagName)) {
    // 模糊查询
    Tag.list({ tagName }, false)
      .then(({ result }) => {
        tagList.value = result
      })
      .finally(() => {
        openTagSearchLoading.value = false
      })
  } else {
    // 查询常用的
    Tag.list({ frequent: true }, false)
      .then(({ result }) => {
        tagList.value = result
      })
      .finally(() => {
        openTagSearchLoading.value = false
      })
  }
}

// 新增的标签名称
const tagName = ref('')

// 打开新增标签的输入框
const addTagInputShow = ref(false)

// 打开新增标签的输入框
function openAddTagInput() {
  addTagInputShow.value = true
}

// 新增一个标签
function addTag() {
  let tag = tagName.value
  if (isNotEmpty(tag)) {
    Tag.create(tag).then(({ code }) => {
      if (code === 200) {
        // 新增成功，将该标签与文章绑定
        tagList.value.unshift(tag)
        tagSelectedList.value.push(tag)
        tagName.value = ''
      }
    })
  }
}

// 取消新增标签
function cancelAddTag() {
  tagName.value = ''
  addTagInputShow.value = false
}
</script>

<style scoped lang="scss"></style>
